import { ElMessage, ElLoading } from 'element-plus'
import { getToken } from '@/utils/auth'
import service from '@/utils/request'
import { tansParams, blobValidate } from '@/utils/ruoyi'
import errorCode from '@/utils/errorCode'

/**
 * 从文件路径中提取文件名
 * @param {string} path - 文件路径
 * @returns {string} 文件名
 */
export function getFileNameFromPath(path = '') {
  if (!path) return ''
  const segments = path.split('/')
  return segments.pop() || ''
}

/**
 * 下载文件（通过文件路径）
 * @param {string|object} file - 文件路径字符串或包含 filePath/url 的对象
 * @returns {Promise<void>}
 */
export async function downloadFile(file) {
  const baseUrl = import.meta.env.VITE_APP_BASE_API
  let filePath = file.filePath || file.url || file

  if (!filePath) {
    ElMessage.warning('文件路径不存在')
    return
  }

  // 构建完整 URL
  let fileUrl = filePath
  if (!filePath.startsWith('http://') && !filePath.startsWith('https://')) {
    fileUrl = baseUrl + (filePath.startsWith('/') ? filePath : '/' + filePath)
  }

  // 显示加载提示
  const loadingInstance = ElLoading.service({
    text: '正在下载文件，请稍候',
    background: 'rgba(0, 0, 0, 0.7)',
  })

  try {
    // 使用 fetch 获取文件
    const response = await fetch(fileUrl, {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${getToken()}`,
      },
    })

    if (!response.ok) {
      throw new Error(`下载失败: ${response.status} ${response.statusText}`)
    }

    // 转换为 blob
    const blob = await response.blob()

    // 获取文件名：优先使用 file.fileName 或 file.name，其次从响应头获取，最后从路径提取
    const contentDisposition = response.headers.get('content-disposition')
    let fileName = ''
    
    // 优先使用对象的 fileName 或 name 属性
    if (typeof file === 'object' && (file.fileName || file.name)) {
      fileName = file.fileName || file.name
    } else if (contentDisposition) {
      // 其次从响应头获取
      const fileNameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)
      if (fileNameMatch && fileNameMatch[1]) {
        fileName = decodeURIComponent(fileNameMatch[1].replace(/['"]/g, ''))
      }
    }
    
    // 最后从路径提取
    if (!fileName) {
      fileName = getFileNameFromPath(filePath)
    }

    // 创建对象 URL
    const objectUrl = URL.createObjectURL(blob)

    // 创建 a 标签触发下载
    const link = document.createElement('a')
    link.href = objectUrl
    link.download = fileName
    document.body.appendChild(link)
    link.click()

    // 清理
    document.body.removeChild(link)
    URL.revokeObjectURL(objectUrl)

    ElMessage.success('文件下载成功')
  } catch (error) {
    console.error('下载文件失败:', error)
    ElMessage.error('下载文件失败，请重试')
  } finally {
    loadingInstance.close()
  }
}

/**
 * 通过 API 接口下载文件（处理 blob 响应）
 * @param {string} url - API 接口地址
 * @param {object} params - 请求参数
 * @param {string} filename - 文件名
 * @param {object} config - 额外配置
 * @returns {Promise<void>}
 */
export async function downloadFileByApi(url, params, filename, config = {}) {
  // 显示加载提示
  const loadingInstance = ElLoading.service({
    text: '正在下载文件，请稍候',
    background: 'rgba(0, 0, 0, 0.7)',
  })

  try {
    // 使用 axios 请求 API
    const data = await service.post(url, params, {
      transformRequest: [(params) => { return tansParams(params) }],
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      responseType: 'blob',
      ...config
    })

    // 验证是否为 blob
    const isBlob = blobValidate(data)
    if (isBlob) {
      // 获取文件名
      let fileName = filename || `download_${Date.now()}`

      // 创建 blob
      const blob = new Blob([data])

      // 创建对象 URL
      const objectUrl = URL.createObjectURL(blob)

      // 创建 a 标签触发下载
      const link = document.createElement('a')
      link.href = objectUrl
      link.download = fileName
      document.body.appendChild(link)
      link.click()

      // 清理
      document.body.removeChild(link)
      URL.revokeObjectURL(objectUrl)

      ElMessage.success('文件下载成功')
    } else {
      // 处理错误响应
      const resText = await data.text()
      const rspObj = JSON.parse(resText)
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      ElMessage.error(errMsg)
    }
  } catch (error) {
    console.error('下载文件失败:', error)
    ElMessage.error('下载文件失败，请重试')
  } finally {
    loadingInstance.close()
  }
}

